Skip to content

Add aws-lc-rs crypto backend with trait-based abstraction#320

Open
preuss-adam wants to merge 4 commits into
eclipse-biscuit:mainfrom
preuss-adam:crypto-traits
Open

Add aws-lc-rs crypto backend with trait-based abstraction#320
preuss-adam wants to merge 4 commits into
eclipse-biscuit:mainfrom
preuss-adam:crypto-traits

Conversation

@preuss-adam
Copy link
Copy Markdown

Summary

  • Add trait-based crypto backend abstraction (Backend, KeyPairImpl, PrivateKeyImpl, PublicKeyImpl, KeySerialization, KeyPemSerialization)
  • Move existing ed25519-dalek/p256 code into default/ backend implementing the new traits
  • Add aws-lc-rs backend with Ed25519 and secp256r1 support
  • Feature-gate backends: default-backend (ed25519-dalek/p256) and awslc-backend (aws-lc-rs)
  • Remove unused deps: sha2, prost-types, getrandom, ecdsa, elliptic-curve
  • Upgrade pkcs8 to 0.10.2

Benchmarks

Ed25519 verification (third-party checks)

Blocks default-backend awslc-backend Speedup
0 85us 56us 1.5x
1 108us 78us 1.4x
2 167us 113us 1.5x
3 197us 148us 1.3x
4 241us 185us 1.3x
5 285us 222us 1.3x
6 337us 253us 1.3x
7 374us 289us 1.3x

P256 verification (third-party checks)

Blocks default-backend awslc-backend Speedup
0 406us 76us 5.3x
1 731us 127us 5.8x
2 975us 185us 5.3x
3 1,253us 230us 5.4x
4 1,561us 284us 5.5x
5 1,847us 338us 5.5x
6 2,091us 393us 5.3x
7 2,445us 446us 5.5x

Usage

Default (ed25519-dalek + p256):

biscuit-auth = "6.0.0"

aws-lc-rs backend:

biscuit-auth = { version = "6.0.0", default-features = false, features = ["awslc-backend", "pem", "regex-full", "datalog-macro"] }

- Add traits.rs with Backend, KeyPairImpl, PrivateKeyImpl, PublicKeyImpl
- Add KeySerialization and KeyPemSerialization traits
- Wire mod traits into crypto module
- Move ed25519.rs and p256.rs into default/ submodule
- Implement KeyPairImpl, PrivateKeyImpl, PublicKeyImpl traits on default backend types
- Rewrite mod.rs to use DefaultBackend + trait-based type aliases
- Update scope.rs Display impl for new PublicKey type
- Implement Ed25519 and secp256r1 PublicKey, PrivateKey, KeyPair
- Add AwsLcPublicKey trait with blanket KeyPemSerialization impl
- Add P256 point compression/decompression via aws-lc-sys FFI
- Add aws-lc-rs, aws-lc-sys deps; upgrade pkcs8 to 0.10.2
- Remove unused deps: sha2, prost-types, getrandom, ecdsa, elliptic-curve
- Add tests for sign/verify, serialization, PEM/DER roundtrips
- Make ed25519-dalek, p256, aws-lc-rs, aws-lc-sys optional deps
- Add default-backend and awslc-backend feature flags
- Add default-backend-pem synthetic feature for dalek pem/pkcs8
- Make pem feature standalone
- Gate awslc module with not(default-backend) to prevent conflicting impls
- default-backend takes priority when both features are enabled
@divarvel
Copy link
Copy Markdown
Contributor

hi, as an update, i still plan on reviewing this; thanks for your patience.

Copy link
Copy Markdown
Contributor

@divarvel divarvel left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

One of the pending projects that’s related to this effort is allowing the use of a KMS, same as what was done in biscuit-java eclipse-biscuit/biscuit-java#113

I think the traits, as they are designed, would work, but the naming would be a bit misleading, as they focus on abstracting over things (public key, private key) instead of the actual behavior (signing, verifying).
The traits as they are defined have a granularity that would fit the bill (especially separating the key serialization functions), but the traits constraints as they stand would not allow using a KMS for the authority key and a regular keypair for attenuation keys. I feel that would be resolved by adding an equivalent of BiscuitBuilder::build that would be generic on the signer argument (maybe with a default defined with cfg macros).

Finally, and that’s really nitpicking, I was a bit taken aback by the xxImpl naming for a trait.

I think we should design things around two main traits:

Signer, used in BiscuitBuilder::build() and ThirdPartyRequest::create_block(). types implementing it are able to sign a payload, expose a public key and declare their algorithm.
KeyPair, used in Biscuit::append(). Types implementing it can be generated, expose a public and private key that can be serialized / deserialized and declare their algorithm.

Those two traits would handle the places where the biscuit impl itself needs to call out to the crypto layer. For the rest, there is no strong need to be generic, since it’s code written by library users (still, defining a trait would make things a bit nicer to user by enforcing consistency between implementations).
imo, moving parametricity to actual call sites in the biscuit library would let us get on by with smaller traits and simpler code, and default generic types defined through cfg attributes would keep the nice property of deciding which implementation to use through cargo features, while keeping the opportunity to strategically override things

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants